#include "HashObject.hpp"
#include "../../base/Defind.hpp"

using namespace DBServer::Database;
using CallBack = std::function<void(HashObject&, CommandRequest&&, CommandRespond&)>;

std::unordered_map<int, CallBack>
HashObject::cb_table([]{    
    std::unordered_map<int, CallBack> temp;

    temp[COMMAND_GET] = [](HashObject& ho, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ho.get();
        // translate the std::pair to string
        auto ret_string = Translator::vector_to_string(ret);
        crp.respond = ret_string;
    };

    temp[COMMAND_HADD] = [](HashObject& ho, CommandRequest&& crq, CommandRespond& crp){
        std::string key{""};
        std::string value{""};
        std::string &tmp = key;
        // initialize the key and value
        for (char c : crq.command[COMMAND_VALUE])
        {
            if (c == ' ')
            {
                tmp = value;
                continue;
            }
            tmp += c;
        }

        auto ret = ho.hadd(std::move(key), std::move(value));

        if (ret)
        {
            crp.respond = OK;
        }
        else 
        {
            crp.respond = HADD_FAULT;
        }
    };

    temp[COMMAND_HSIZE] = [](HashObject& ho, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ho.hsize();
        crp.respond = Translator::int_to_string(ret);
    };

    temp[COMMAND_HEXIST] = [](HashObject& ho, CommandRequest&& crq, CommandRespond& crp){
        std::pair<std::string, std::string> entry;
        auto ret = ho.hexist(std::move(crq.command[COMMAND_VALUE]), entry);

        if (!ret) 
        {
            crp.respond = HEXIST_FAULT;
        }
        else
        {
            crp.respond = entry.first + ":" + entry.second;
        }

    };

    temp[COMMAND_HREMOVE] = [](HashObject& ho, CommandRequest&& crq, CommandRespond& crp){
        auto ret = ho.hremove(std::move(crq.command[COMMAND_VALUE]));
        if (ret)
        {
            crp.respond = OK;
        }
        else
        {
            crp.respond = HREMOVE_FAULT;
        }
    };

    return temp;
}());

void
HashObject::command_excute(CommandRespond& crp, CommandRequest&& crq, com_func_t& cft)
{
    cb_table[cft.second](*this, std::move(crq), crp);
}